#include <stdio.h>
#include <stdlib.h>

#define SIZE 65537
int hashv(int v){
    return v%SIZE;
}

typedef struct _ht ht;
struct _ht {
    struct _htNode **hn;
    int size;
    int (*hashFunc)(int);
};

typedef struct _htNode htNode;
struct _htNode{
    int key;
    int count;
    struct _htNode *next;
};

ht *htInit();
htNode* find(ht*,int);
void add(ht*,int);
void addCnt(htNode*);
void delCnt(htNode*);
void del(ht*,int);
void htDel(ht*);

ht *htInit(){
    ht *h=malloc(sizeof(ht));
    h->hn=malloc(sizeof(htNode*)*SIZE);
    for(int i=0; i<SIZE; i++)
        h->hn[i]=NULL;
    h->size=0;
    h->hashFunc=hashv;
    return h;
}

htNode* find(ht* h,int key){
    int hashv=h->hashFunc(key);
    htNode *hn=h->hn[hashv];
    while( hn ){
        if( hn->key == key )
            return hn;
        hn=hn->next;
    }
    return NULL;
}

void add(ht* h,int key){
    int hashv=h->hashFunc(key);
    htNode *n=malloc(sizeof(htNode));
    n->key=key;
    n->count=1;
    n->next=h->hn[hashv];
    h->hn[ hashv ]=n;
    return ;
}

void addCnt(htNode* hn){
    hn->count++;
    return;
}
/*j
void delCnt(htNode* hn){
    hn->count--;
    return;
}*/
void del(ht* h,int key){
    int hashv=h->hashFunc(key);
    htNode *hn=h->hn[hashv];
    htNode **father=&(h->hn[hashv]);
    while( hn ){
        if( hn->key == key ){
            if( hn->count == 1){
                *father=hn->next;
                free(hn);
            }else
                hn->count--;
            break;
        }
        // *father=hn->next;
        father=&(hn->next);
        hn=hn->next;
    }
    return ;
}

void htDel(ht* h){
    htNode *hn=NULL,*tmp;
    for( int i=0; i<SIZE; i++ ){
        hn=h->hn[i];
        while( hn ){
            tmp=hn->next;
            free(hn);
            hn=tmp;
        }
    }
    free(h->hn);
    free(h);
    return ;
}

#define Max(a,b) ((a)>(b)?(a):(b))

long long maxSum(int* nums, int numsSize, int m, int k) {
    ht *h=htInit();
    long long max=0,cursum=0;
    int match=0;
    htNode *result=NULL;
    for( int i=0; i< numsSize; i++ ){
        cursum+=nums[i];
        result=find(h,nums[i]);
        if( !result ){
            match++;
            add(h,nums[i]);
        }
        else
            addCnt(result);
        if( i < k-1 )
            continue;
        if( match >= m )
            max=Max(max,cursum);
        cursum-=nums[ i+1-k ];
        del(h,nums[ i+1-k ]);
        result=find(h,nums[ i+1-k ]);
        if( !result )
            match--;
    }
    htDel(h);
    return max;
}
int main(){
    int nums[]={1,2,1,2,1,2,1};
    printf("%lld\n",maxSum(nums,sizeof(nums)/sizeof(int),3,3));
    return 0;
}
